<?php
/*
 * Copyright (c) 2022.  Liuhongbin All rights reserved.
 * @domain http://dkyx.cc
 * @author liuhongbin <514660094@qq.com>
 */

/**
 * @Author: liuhongbin
 * @Email: 514660094@qq.com
 * @Date: 2019-02-12 16:15:10
 * @Description:
 * @LastEditors: liuhongbin
 * @LastEditTime: xxx
 */

namespace hiduoke\services\douyin;


use GuzzleHttp\Client as GuzzleClient;
use think\facade\Cache;

class DouyinHttp
{
    protected $baseUrl = 'https://open.douyin.com';
    protected array        $guzzleOptions = [];
    protected $path = "";
    /**
     * @var GuzzleClient
     */
    protected $httpClient;
    protected $options = [];
    protected $access_token;

    public function __construct($user)
    {
        $this->user = $user;
        $this->access_token = $user['access_token'];
    }

    /**
     * @param string $path
     * @param array $query
     * @return array|mixed
     */
    public function get($path = '', $query = [])
    {
        $query['open_id'] = $this->user['open_id'];
        $query = array_merge(['access_token' => $this->access_token], $query);
        return $this->request('get', $path, [
            'headers' => [
                'Accept'       => 'application/json',
                'access-token' => $this->access_token
            ],
            'query'   => $query
        ]);
    }

    public function getCache($path = '', $query = [], $refresh = false)
    {
        $query['open_id'] = $this->user['open_id'];
        $query = array_merge(['access_token' => $this->access_token], $query);
        $key = $this->getCacheKey($path, $query);
        $data = Cache::get($key);
        if ($data && !$refresh) {
            Cache::set($key, $data);
            return $data;
        } else {
            $data = $this->get($path, $query);
            if($data['error_code'] == 0){
                Cache::set($key, $data);
            }
            return $data;
        }
    }

    public function postCache($path = '', $query = [], $data = [], $refresh = false)
    {
        $query['open_id'] = $this->user['open_id'];
        $query = array_merge(['access_token' => $this->access_token], $query);
        $key = $this->getCacheKey($path, $query, $data);
        $data = Cache::get($key);
        if ($data && !$refresh) {
            return $data;
        } else {
            $data = $this->post($path, $query, $data);
            Cache::set($key, $data);
            return $data;
        }
    }

    /**
     * @param string $path
     * @param array $query
     * @param array $data
     * @return array|mixed
     */
    public function post($path = '', $query = [], $data = [])
    {
        $query['open_id'] = $this->user['open_id'];
        return $this->request('post', $path, [
            'headers' => [
                'Accept'       => 'application/json',
                'access-token' => $this->access_token
            ],
            'json'    => $data,
            'query'   => $query
        ]);
    }

    /**
     * @return GuzzleClient
     */
    public function getHttpClient(): GuzzleClient
    {
        return $this->httpClient ?? new GuzzleClient($this->guzzleOptions);
    }

    /**
     * @param string $method
     * @param string $path
     * @param array $options
     * @return array|mixed
     */
    public function request($method = 'get', $path = "", $options = [])
    {
        $apiUrl = $this->baseUrl . $path;
        $response = $this->getHttpClient()->$method($apiUrl, $options);
        $body = \json_decode($response->getBody()->getContents(), true);
        return $body['data'] ?? [];
    }

    /**
     * @param array $config
     * @return $this
     */
    public function setGuzzleOptions($config = [])
    {
        $this->guzzleOptions = $config;
        return $this;
    }

    /**
     * @return array
     */
    public function getGuzzleOptions(): array
    {
        return $this->guzzleOptions;
    }

    protected function getCacheKey($path = '', $query = [], $data = [])
    {
        $key = "dy-" . md5(json_encode($query)) . '-' . md5(json_encode($data)) . $path;
        return $key;
    }
}
